package com.avalon.core.db;

import com.avalon.core.context.Context;
import com.avalon.core.exception.AvalonException;
import com.avalon.core.exception.SQLFormatException;
import com.avalon.core.field.Field;
import com.avalon.core.field.Fields;
import com.avalon.core.field.IFieldFormat;
import com.avalon.core.model.Record;
import com.avalon.core.model.RecordRow;
import com.avalon.core.select.SelectionField;
import com.avalon.core.service.AbstractService;
import com.avalon.core.util.FieldUtils;
import com.avalon.core.util.FieldValue;
import com.avalon.core.util.ObjectUtils;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.jdbc.core.RowCountCallbackHandler;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;

@EqualsAndHashCode(callSuper = true)
@Data
public class DefaultDataReaderRowHandler  extends RowCountCallbackHandler {

    private AbstractService abstractService;

    private Record record = new Record();
    private HashMap<String, SelectionField> selectionFields = new HashMap<>();

    public DefaultDataReaderRowHandler() {

    }

    public DefaultDataReaderRowHandler(AbstractService abstractService) {
        this.abstractService = abstractService;
    }

    @Override
    protected void processRow(ResultSet rs, int rowNum) throws SQLException {

        if (ObjectUtils.isNull(record)) {
            record = new Record();
        }
        RecordRow recordRow = new RecordRow();
        for (String sqlName : getColumnNames()) {
            String fieldName;
            fieldName = Fields.camelName(FieldUtils.getJoinFieldString(sqlName));

            Field field = abstractService.getField(fieldName);
            Object sqlValue = rs.getObject(sqlName);
            if (ObjectUtils.isNull(sqlValue)) {
                recordRow.put(FieldUtils.getJoinDisplayString(fieldName), null);
                continue;
            }
            if (field instanceof IFieldFormat) {
                IFieldFormat fieldFormat = (IFieldFormat) field;
                try {
                    FieldValue fieldValue = new FieldValue(fieldFormat.parse(sqlValue));
                    fieldValue.setField(fieldFormat);
                    recordRow.put(FieldUtils.getJoinDisplayString(fieldName), fieldValue);
                } catch (AvalonException e) {
                    String msg = "字段=" + field.getName() + ",类型=" + field.getClass().getTypeName()
                            + ",格式=" + fieldFormat.getFormat() + ",值=" + sqlValue;
                    Context.getLogger(this).error(msg);
                    throw new SQLFormatException(msg);
                }
            } else {
                recordRow.put(FieldUtils.getJoinDisplayString(fieldName), sqlValue);
            }
        }

        record.add(recordRow);

    }
}
